package com.rtx.edi.platform.handler;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.rtx.edi.model.api.po.PlApiMappingStructure;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

public class JsonConvert {


    /**
     * 源JSON
     */
    private String sourceJosn;

    /**
     * 目标JSON
     */
    private String targetJosn;

    /**
     * JSON字段映射关系
     */
    private List<PlApiMappingStructure> structureList;

    /**
     * 全局变量
     */
    private Map<String, Map<String, Object>> globalMap;

    public JsonConvert(String sourceJosn, String targetJosn, List<PlApiMappingStructure> structureList, Map<String, Map<String, Object>> globalMap) {
        this.sourceJosn = sourceJosn;
        this.targetJosn = targetJosn;
        this.structureList = structureList;
        this.globalMap = globalMap;
    }

    public void convert(){
        if(CollectionUtils.isEmpty(this.structureList)){
            this.targetJosn = this.sourceJosn;
        } else if(!StringUtils.hasText(this.targetJosn)){
            this.targetJosn = this.sourceJosn;
        }else if(this.targetJosn.startsWith("{")){
            convertObject();
        }else if(this.targetJosn.startsWith("[")){
            convertArray();
        }else{
            throw new RuntimeException("目标JSON模板格式错误");
        }
    }

    /**
     * 转化数组
     */
    private void convertArray() {
        JSONArray target = JSONUtil.parseArray(this.targetJosn);
        if(this.sourceJosn.startsWith("{")){
            JSONObject temp = new JSONObject();
            JSONObject source = JSONUtil.parseObj(this.sourceJosn);
            convertTargetJosn("",temp,source,null);
            target.putByPath("[0]",temp);
        }else if(this.sourceJosn.startsWith("[")){
            JSONArray array = JSONUtil.parseArray(this.sourceJosn);
            for(int i = 0; i < array.size(); i++){
                JSONObject temp = new JSONObject();
                JSONObject source = array.getJSONObject(i);
                convertTargetJosn("",temp,source,null);
                target.putByPath("[" + i + "]",temp);
            }
        }
        this.targetJosn = target.toString();
    }

    /**
     * 转化对象
     */
    private void convertObject() {
        JSONObject target = JSONUtil.parseObj(this.targetJosn);
        JSONObject source = JSONUtil.parseObj(this.sourceJosn);
        convertTargetJosn("",target,source,null);
        this.targetJosn = target.toString();
    }

    /**
     * 转化目标JSON
     * @param target
     * @param source
     */
    private void convertTargetJosn(String parent,JSONObject target,JSONObject source,List<String> indexs){
        for(Map.Entry<String, Object> entry : source.entrySet()){
            //获取节点值
            Object value = entry.getValue();
            //获取字段映射
            PlApiMappingStructure structure = this.structureList.stream()
            								.filter(s -> 
            								entry.getKey().equals(s.getSourceFieldName()) && 
            								(parent+entry.getKey()).equals(s.getSourceFieldPath().replaceAll("数组", ""))&&
            								(!Arrays.asList("object,array".split(",")).contains(s.getTargetFieldType()))
            								)
            								.findAny()
            								.orElse(null);
            if(value instanceof JSONObject){
                convertTargetJosn(parent + entry.getKey() + ".",target,(JSONObject) value,null);
            }else if(value instanceof JSONArray){
                JSONArray temp = (JSONArray) value;
                for(int i = 0; i < temp.size(); i++){
                    if(indexs == null){
                        indexs = new ArrayList<>();
                    }
                    Object o = temp.get(i);
                    if(o instanceof JSONObject){
                        indexs.add(String.valueOf(i));
                        convertTargetJosn(parent + entry.getKey() + ".",target, (JSONObject) o,indexs);
                    }else{
                        if(structure != null){
                            String path = structure.getTargetFieldPath();
                            path = StrUtil.replaceLast(path,"数组","[" + i + "]");
                            path = handTargetPath(path,indexs);
                            if("true".equals(structure.getChecknull())) {
                            	if(null == o) {
                            		throw new RuntimeException(path+"值不能为空！");
                            	}
                            }
                            target.putByPath(path,o);
                        }
                    }
                }
            }else{
                if(structure != null){
                	List<PlApiMappingStructure> structureList = this.structureList.stream().filter(s -> 
					entry.getKey().equals(s.getSourceFieldName()) && 
					(parent+entry.getKey()).equals(s.getSourceFieldPath().replaceAll("数组", ""))&&
					(!Arrays.asList("object,array".split(",")).contains(s.getTargetFieldType()))
                	).collect(Collectors.toList());
                	for(PlApiMappingStructure tempStructure:structureList) {
                		String path = handTargetPath(tempStructure.getTargetFieldPath(),indexs);
                        if("true".equals(structure.getChecknull())) {
                        	if(null == value) {
                        		throw new RuntimeException(path+"值不能为空！");
                        	}
                        }
                		if(null != value) {
                			target.putByPath(path,value);
                		}
                	}
                }
            }
        }
    }

    /**
     * 处理目标路径
     * @param path
     * @param indexs
     * @return
     */
    private String handTargetPath(String path,List<String> indexs){
        if(!CollectionUtils.isEmpty(indexs)){
            for(int i = indexs.size() - 1; i >= 0; i--){
                path = StrUtil.replaceLast(path,"数组","[" + indexs.get(i) + "]");
            }
        }
        if(path.contains("数组")){
            path = path.replaceAll("数组","[0]");
        }
        return path;
    }

    public String getSourceJosn() {
        return sourceJosn;
    }

    public void setSourceJosn(String sourceJosn) {
        this.sourceJosn = sourceJosn;
    }

    public String getTargetJosn() {
        return targetJosn;
    }

    public void setTargetJosn(String targetJosn) {
        this.targetJosn = targetJosn;
    }

    public List<PlApiMappingStructure> getStructureList() {
        return structureList;
    }

    public void setStructureList(List<PlApiMappingStructure> structureList) {
        this.structureList = structureList;
    }

    public Map<String, Map<String, Object>> getGlobalMap() {
        return globalMap;
    }

    public void setGlobalMap(Map<String, Map<String, Object>> globalMap) {
        this.globalMap = globalMap;
    }


//    public static void main(String[] args) {
//		String str ="{\"NeedUpDateFields\":[],\"NeedReturnFields\":[],\"IsDeleteEntry\":\"true\",\"SubSystemId\":\"\",\"IsVerifyBaseDataField\":\"false\",\"IsEntryBatchFill\":\"true\",\"ValidateFlag\":\"true\",\"NumberSearch\":\"true\",\"IsAutoAdjustField\":\"false\",\"InterationFlags\":\"\",\"IgnoreInterationFlag\":\"\",\"IsControlPrecision\":\"false\",\"ValidateRepeatJson\":\"false\",\"Model\":{\"FID\":0,\"FBillType\":{\"FNUMBER\":\"\"},\"FDate\":\"1900-01-01\",\"FStockOrgId\":{\"FNumber\":\"\"},\"FStockId0\":{\"FNumber\":\"\"},\"FPrdOrgId\":{\"FNumber\":\"\"},\"FWorkShopId\":{\"FNumber\":\"\"},\"FOwnerTypeId0\":\"\",\"FOwnerId0\":{\"FNumber\":\"\"},\"FSTOCKERID\":{\"FNAME\":\"\"},\"FDescription\":\"\",\"FIsEntrust\":\"false\",\"FCurrId\":{\"FNumber\":\"\"},\"FEntrustInStockId\":0,\"FScanBox\":\"\",\"F_FSCA_CheckBox\":\"false\",\"F_FSCA_PrintTimes\":0,\"F_FSCA_Text2\":\"\",\"FSynchState\":\"\",\"FEntity\":[{\"FEntryID\":0,\"FSrcEntryId\":0,\"FIsNew\":\"false\",\"FMaterialId\":{\"FNumber\":\"\"},\"FMemo\":\"\",\"FCheckProduct\":\"false\",\"FProductType\":\"\",\"FInStockType\":\"\",\"FUnitID\":{\"FNumber\":\"\"},\"FMustQty\":0,\"FRealQty\":0,\"FCostRate\":0,\"FBaseUnitId\":{\"FNumber\":\"\"},\"FBaseMustQty\":0,\"FBaseRealQty\":0,\"FOwnerTypeId\":\"\",\"FOwnerId\":{\"FNumber\":\"\"},\"FStockId\":{\"FNumber\":\"\"},\"FStockLocId\":{\"FSTOCKLOCID__FF100001\":{\"FNumber\":\"\"},\"FSTOCKLOCID__FF100002\":{\"FNumber\":\"\"},\"FSTOCKLOCID__FF100003\":{\"FNumber\":\"\"},\"FSTOCKLOCID__FF100004\":{\"FNumber\":\"\"}},\"FBomId\":{\"FNumber\":\"\"},\"FLot\":{\"FNumber\":\"\"},\"FISBACKFLUSH\":\"false\",\"FMtoNo\":\"\",\"FProjectNo\":\"\",\"FWorkShopId1\":{\"FNumber\":\"\"},\"FShiftGroupId\":{\"FNumber\":\"\"},\"FLINEID\":{\"FNUMBER\":\"\"},\"FMoBillNo\":\"\",\"FMoId\":0,\"FMoEntryId\":0,\"FMoEntrySeq\":0,\"FStockUnitId\":{\"FNumber\":\"\"},\"FStockRealQty\":0,\"FSecUnitId\":{\"FNumber\":\"\"},\"FSecRealQty\":0,\"FAuxpropId\":{\"FAUXPROPID__FF100002\":{\"FNumber\":\"\"},\"FAUXPROPID__FF100001\":\"\",\"FAUXPROPID__FF100003\":\"\"},\"FSrcBillType\":\"\",\"FSrcInterId\":0,\"FSrcBillNo\":\"\",\"FBasePrdRealQty\":0,\"FIsFinished\":\"false\",\"FStockStatusId\":{\"FNumber\":\"\"},\"FSrcEntrySeq\":0,\"FMOMAINENTRYID\":0,\"FKeeperTypeId\":\"\",\"FKeeperId\":{\"FNumber\":\"\"},\"FProduceDate\":\"1900-01-01\",\"FSelReStkQty\":0,\"FExpiryDate\":\"1900-01-01\",\"FBaseSelReStkQty\":0,\"FSrcBusinessType\":\"\",\"F_FSCA_Text\":\"\",\"F_FSCA_Qty\":0,\"FIsOverLegalOrg\":\"false\",\"FSendRowId\":\"\",\"F_FSCA_Base\":{\"FNUMBER\":\"\"},\"F_FSCA_Text1\":\"\",\"F_FSCA_Assistant\":{\"FNumber\":\"\"},\"FWMSID\":\"\",\"FSerialSubEntity\":[{\"FDetailID\":0,\"FSerialNo\":\"\",\"FSerialId\":{\"FNumber\":\"\"},\"FQty\":0,\"FBaseSNQty\":0,\"FSerialNote\":\"\"}]}]}}";
//		String path ="Model.FEntity[0].FMaterialId.FNumber";
//		JSONObject target = JSONUtil.parseObj(str);
//		target.putByPath(path, "1");
//		System.out.println("1");
//	}
}
